home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / ch_5.7 / eh_sgl / eh_sgl.c next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  12.3 KB  |  512 lines

  1. /* 
  2.  * eh_sgl.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /*
  10.  * E(xtract) H(istograms)_SGL
  11.  *
  12.  * routine to extract desired set of parameters from a data file of 
  13.  * type .SGL whose name is entered as a command line argument and 
  14.  * construct a histogram; write output file of type *.hdt
  15.  *
  16.  */
  17. #include "eh_sgl.h"
  18.  
  19. #define    LINE_LEN    80             /* max length of line in data file */
  20. #define    TITLE_LEN    30            /* max length of line title */
  21. #define    FN_LEN        10              /* length of data file name */
  22.  
  23. #define BIN_NUMBER    10           /* no bins in histogram */
  24. #define    READ_SEGM    0
  25. #define    READ_AREA    1
  26. #define    READ_LEN    2
  27. #define    READ_WIDTH    3
  28. #define    READ_HAREA    4
  29. #define    READ_QUOT    5
  30. #define    SEGM_HIST    "\nhistogram for SGL segment number"
  31. #define    AREA_HIST    "\nhistogram for polygon area"
  32. #define    LEN_HIST    "\nhistogram for polygon length"
  33. #define    WIDTH_HIST    "\nhistogram for polygon width"
  34. #define    CH_AREA_HIST    "\nhistogram for convex hull area"
  35. #define    QUOT_HIST    "\nhistogram for quotient of poly area and hull area"
  36.  
  37. #define    ON         1
  38. #define    OFF         0
  39.  
  40. #undef    SHOW_SORT
  41.  
  42. /*
  43.  * ** global variables
  44.  */
  45. extern char *optarg;
  46. extern int optind, opterr;
  47.  
  48.  
  49. static char *HIST_HEADER;
  50. int MAKE_HIST = -1;
  51. int N_BINS = BIN_NUMBER;
  52. int MIN_SET = 0;
  53. int MAX_SET = 0;
  54. int SAVE_VERT = 0;              /* vertex coordinates stored in .sgl file */
  55. int WRITE_FILE = 0;
  56. int SHOW_INPUT = 1;
  57.  
  58. /*
  59.  * usage of routine
  60.  */
  61. void
  62. usage (char *progname)
  63. {
  64.   progname = last_bs (progname);
  65.   printf ("USAGE: %s infile [-v] [-d] [-s] [-a] [-l] [-b] [-h] [-q]\n", progname);
  66.   printf ("                 [-n n] [-i f] [-f f] [-w] [-L]\n");
  67.   printf ("\n%s extracts histogram data from SGL output files created by xsgll\n\n", progname);
  68.   printf ("ARGUMENTS:\n");
  69.   printf ("  infile: input filename (SGL)\n\n");
  70.   printf ("OPTIONS:\n");
  71.   printf ("    -v: expect vertex coordinates in .sgl file\n");
  72.   printf ("    -d: disply input data\n\n");
  73.   printf ("    construct histogram for:\n");
  74.   printf ("    -s: segment number (per SGL)\n");
  75.   printf ("    -a: area\n");
  76.   printf ("    -l: length\n");
  77.   printf ("    -b: width\n");
  78.   printf ("    -h: (convex) hull area\n");
  79.   printf ("    -q: quotient area/conv hull area\n\n");
  80.   printf ("  -n n: set number of bins to n (default: 10)\n");
  81.   printf ("  -i f: set initial value to f(float)\n");
  82.   printf ("  -f f: set final value to f(float)\n");
  83.   printf ("    -w: write output file of type .hdt (hist data)\n");
  84.   printf ("    -L: print Software License for this module\n");
  85.   exit (1);
  86. }
  87.  
  88.  
  89.  
  90. /*
  91.  * ** comparison function for qsort():
  92.  * ** sort array of tuples in order of increassing x-values
  93.  */
  94. int 
  95. compare (t1, t2)
  96.      float *t1, *t2;
  97. {
  98.   return ((int) SIGN (*t1 - *t2));
  99. }
  100.  
  101.  
  102. /*
  103.  * ** determine mean of input data set
  104.  */
  105. double 
  106. find_mean (float *data, int n)
  107. {
  108.   int i;
  109.   double mean = 0.0;
  110.  
  111.   for (i = 0; i < n; i++)
  112.     mean += *(data + i);
  113.  
  114.   return (mean / (double) n);
  115. }
  116.  
  117. /*
  118.  * ** determine standard deviation of input data set
  119.  */
  120. double 
  121. find_sigma (float *data, int n, double mean)
  122. {
  123.   int i;
  124.   double xi, sigma = 0.0;
  125.  
  126.   for (i = 0; i < n; i++) {
  127.     xi = (double) (*(data + i));
  128.     sigma += (xi - mean) * (xi - mean);
  129.   }
  130.   sigma /= (double) (n - 1);
  131.  
  132.   return (sqrt (sigma));
  133. }
  134.  
  135.  
  136. /*
  137.  * ** construct histogram of input data
  138.  */
  139. void 
  140. construct_hist (int n, float *data, float *hist, double bw, double data_base)
  141. {
  142.   int i, ibin;
  143.  
  144.   for (i = 0; i < n; i++) {
  145.     if (*(data + i) != 0) {
  146.       ibin = 0;
  147.       while (*(data + i) >= data_base + ibin * bw)
  148.         ibin++;
  149.       *(hist + ibin - 1) += 1;
  150.     }
  151.   }
  152. }
  153.  
  154.  
  155.  
  156. /*
  157.  * ** skip n lines
  158.  */
  159. void 
  160. skip_n_lines (FILE * file_pointer, int n_lines_to_skip)
  161. {
  162.   int i;
  163.   char ch;
  164.  
  165.   for (i = 0; i < n_lines_to_skip; i++) {
  166.     while ((ch = getc (file_pointer)) != '\n');
  167.   }
  168. }
  169.  
  170.  
  171.  
  172. void 
  173. main (argc, argv)
  174.      int argc;
  175.      char *argv[];
  176. {
  177.   int i_arg;
  178.   int i, ich, is;
  179.   int i_sgl, n_sgl;
  180.   int n_vertex;
  181.   char colon, comma, equ, wspace, opar, cpar;
  182.   static char wbuf[20];
  183.   static char *inp_suffix =
  184.   {".sgl"};                     /* default inp file suffix */
  185.   static char *sgl_type =
  186.   {".sgl"};                     /* suffix for .sgl inp file */
  187.   static char *wsuffix =
  188.   {".hdt"};                     /* suffix for output file name */
  189.   char *rbuf;
  190.  
  191.   static char *stop_code =
  192.   {"histogram"};
  193.   int stop_count = 9;
  194.   int proc_flag;
  195.  
  196.   char buf[64];
  197.   char line_title[TITLE_LEN], line_buf[LINE_LEN], fn_buf[13];
  198.  
  199.   int x_ctr, y_ctr;
  200.   int area, h_area;
  201.   float farea, fh_area;
  202.   float len, width;
  203.   int ns;
  204.   float bin_width, min = (float) -1.0, max = (float) -1.0;
  205.   float *data, *hist;
  206.   double mean, std_dev;
  207.   float foo = (float) 1.0;
  208.   int n_parms = 3;
  209.  
  210.   FILE *fpIn, *fpOut;
  211.  
  212. /* 
  213.  * ** cmd line options:
  214.  */
  215.   static char *optstring = "vdsalbhqn:i:f:wL";
  216.  
  217.  
  218. /*
  219.  * ** parse command line
  220.  */
  221.   optind = 2;
  222.   opterr = ON;                  /* give error messages */
  223.  
  224.  
  225.   if (argc < 2)
  226.     usage (argv[0]);
  227.   while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
  228.     switch (i_arg) {
  229.     case 'v':
  230.       printf ("\n...option %c: ", i_arg);
  231.       printf ("expect vertex coord in .sgl file\n");
  232.       SAVE_VERT = ON;
  233.       break;
  234.     case 'd':
  235.       printf ("\n...option %c: ", i_arg);
  236.       printf ("display input data\n");
  237.       SHOW_INPUT = ON;
  238.       break;
  239.     case 's':
  240.       printf ("\n...option %c: ", i_arg);
  241.       printf ("construct histogram for segment number\n");
  242.       MAKE_HIST = READ_SEGM;
  243.       HIST_HEADER = SEGM_HIST;
  244.       break;
  245.     case 'a':
  246.       printf ("\n...option %c: ", i_arg);
  247.       printf ("construct histogram for polygon area\n");
  248.       MAKE_HIST = READ_AREA;
  249.       HIST_HEADER = AREA_HIST;
  250.       break;
  251.     case 'l':
  252.       printf ("\n...option %c: ", i_arg);
  253.       printf ("construct histogram for polygon length\n");
  254.       MAKE_HIST = READ_LEN;
  255.       HIST_HEADER = LEN_HIST;
  256.       break;
  257.     case 'b':
  258.       printf ("\n...option %c: ", i_arg);
  259.       printf ("construct histogram for polygon width\n");
  260.       MAKE_HIST = READ_WIDTH;
  261.       HIST_HEADER = WIDTH_HIST;
  262.       break;
  263.     case 'h':
  264.       printf ("\n...option %c: ", i_arg);
  265.       printf ("construct histogram for conv hull area\n");
  266.       MAKE_HIST = READ_HAREA;
  267.       HIST_HEADER = CH_AREA_HIST;
  268.       break;
  269.     case 'q':
  270.       printf ("\n...option %c: ", i_arg);
  271.       printf ("construct histogram for area/ch_area\nn");
  272.       MAKE_HIST = READ_QUOT;
  273.       HIST_HEADER = QUOT_HIST;
  274.       break;
  275.     case 'n':
  276.       printf ("\n...option %c: ", i_arg);
  277.       printf ("set number of bins to %d\n",
  278.               N_BINS = atoi (optarg));
  279.       break;
  280.     case 'i':
  281.       printf ("\n...option %c: ", i_arg);
  282.       printf ("set min (init value) to %f\n",
  283.               min = (float) atof (optarg));
  284.       MIN_SET = 1;
  285.       break;
  286.     case 'f':
  287.       printf ("\n...option %c: ", i_arg);
  288.       printf ("set max (final value) to %f\n",
  289.               max = (float) atof (optarg));
  290.       MAX_SET = 1;
  291.       break;
  292.     case 'w':
  293.       printf ("\n...option %c: ", i_arg);
  294.       printf ("write output to file %s\n", wbuf);
  295.       WRITE_FILE = 1;
  296.       break;
  297.     case 'L':
  298.       print_sos_lic ();
  299.       exit (0);
  300.     default:
  301.       printf ("\n...unknown cmd line argument\n");
  302.       exit (1);
  303.       break;
  304.     }
  305.   }
  306.  
  307.   printf ("read sgl data from file %s\n",
  308.           rbuf = argv[1]);
  309.   if ((fpIn = fopen (rbuf, "r")) == NULL) {
  310.     printf ("\n...cannot open input file %s\n", rbuf);
  311.     exit (1);
  312.   }
  313.  
  314.   /* construct output file name */
  315.   ich = 0;
  316.   while ((*(wbuf + ich) = *(rbuf + ich)) != '.')
  317.     ich++;
  318.   for (is = 0; is < 4; is++)
  319.     *(wbuf + (ich) + is) = *(wsuffix + is);
  320.   /* strip input file suffix */
  321.   for (is = 0; is < 4; is++)
  322.     *(inp_suffix + is) = *(rbuf + (ich) + is);
  323.   if (strcmp (inp_suffix, sgl_type) != 0) {
  324.     printf ("\n...unknown input file type encountered:");
  325.     printf (" default: %s\n", sgl_type);
  326.     fclose (fpIn);
  327.     exit (1);
  328.   }
  329.  
  330.   if (MAKE_HIST == -1) {
  331.     printf ("\n...problem selecting input for histogram:");
  332.     printf (" MAKE_HIST = %d\n", MAKE_HIST);
  333.     printf ("...select suitable option: -a, -l, -b, -h, -q\n");
  334.     exit (1);
  335.   }
  336.  
  337. /*
  338.  * ** retrieve data from .sgl file
  339.  */
  340.   skip_n_lines (fpIn, 6);
  341.   fgets (line_buf, LINE_LEN, fpIn);
  342.   sscanf (line_buf, "%[^:]%c%s", buf, &colon, fn_buf);
  343.   printf ("\n...data from input file %s\n", fn_buf);
  344.  
  345.   fgets (line_buf, LINE_LEN, fpIn);
  346.   sscanf (line_buf, "%[^:]%c%d", buf, &colon, &n_sgl);
  347.   printf ("total no segment clusters in this file: %d\n", n_sgl);
  348.  
  349.  
  350. /*
  351.  * ** allocate memory for input data
  352.  */
  353.   if ((data = (float *) calloc ((size_t) n_sgl, sizeof (float))) == NULL) {
  354.     printf ("\nEH_SGL: mem alloc for data failed\n");
  355.     exit (1);
  356.   }
  357.  
  358. /*
  359.  * ** scan input file
  360.  */
  361.   skip_n_lines (fpIn, 2);
  362.  
  363.   i_sgl = 0;
  364.   proc_flag = 1;
  365.   do {
  366.     skip_n_lines (fpIn, 1);
  367.     fgets (line_buf, LINE_LEN, fpIn);
  368.     sscanf (line_buf, "%[^:]", line_title);
  369.  
  370.     if ((proc_flag = strncmp (line_title, stop_code, stop_count)) != 0) {
  371.       fgets (line_buf, LINE_LEN, fpIn);
  372.       sscanf (line_buf, "%[^:]%c%d", buf, &colon, &ns);
  373.       fgets (line_buf, LINE_LEN, fpIn);
  374.       sscanf (line_buf, "%[^=]%c%d", buf, &equ, &area);
  375.       farea = (float) area;
  376.       fgets (line_buf, LINE_LEN, fpIn);
  377.       sscanf (line_buf, "%[^=]%c%f%c%[^=]%c%f",
  378.               buf, &equ, &len, &comma, buf, &equ, &width);
  379.  
  380.       if (SAVE_VERT == ON) {    /* vertex coord. stored */
  381.         skip_n_lines (fpIn, 4);
  382.         fgets (line_buf, LINE_LEN, fpIn);
  383.         sscanf (line_buf, "%[^:]%c%d", buf, &colon, &n_vertex);
  384.  
  385.         skip_n_lines (fpIn, 1);
  386.         skip_n_lines (fpIn, n_vertex + 1);
  387.       }
  388.       else                      /* vertex coord not stored */
  389.         skip_n_lines (fpIn, 2);
  390.  
  391.       /* convex hull stats */
  392.       fgets (line_buf, LINE_LEN, fpIn);
  393.       sscanf (line_buf, "%[^=]%c%d", buf, &equ, &h_area);
  394.       fh_area = (float) h_area;
  395.       fgets (line_buf, LINE_LEN, fpIn);
  396.       sscanf (line_buf, "%[^:]%c%c%c%d%c%d%c",
  397.               buf, &colon, &wspace, &opar,
  398.               &x_ctr, &comma, &y_ctr, &cpar);
  399. /*
  400.  * ** write output
  401.  */
  402.       if (SHOW_INPUT == ON) {
  403.         printf ("%s: %3d %6.0f %8.2f %8.2f %6.0f %f\n",
  404.                 line_title, ns, farea, len, width,
  405.                 fh_area, farea / fh_area);
  406.       }
  407.  
  408.       switch (MAKE_HIST) {
  409.       case READ_SEGM:
  410.         *(data + i_sgl) = (float) ns;
  411.         break;
  412.       case READ_AREA:
  413.         *(data + i_sgl) = farea;
  414.         break;
  415.       case READ_LEN:
  416.         *(data + i_sgl) = len;
  417.         break;
  418.       case READ_WIDTH:
  419.         *(data + i_sgl) = width;
  420.         break;
  421.       case READ_HAREA:
  422.         *(data + i_sgl) = fh_area;
  423.         break;
  424.       case READ_QUOT:
  425.         *(data + i_sgl) = farea / fh_area;
  426.         break;
  427.       }
  428.       i_sgl++;
  429.     }
  430.   } while (proc_flag != 0);
  431.  
  432.   n_sgl = i_sgl;
  433.   printf ("total no segment clusters in this file: %d\n", n_sgl);
  434.  
  435. /*
  436.  * ** evaluate statistics
  437.  */
  438.   mean = find_mean (data, n_sgl);
  439.   std_dev = find_sigma (data, n_sgl, mean);
  440.  
  441. /*
  442.  * ** prepare to evaluate histogram
  443.  */
  444. #if defined(LINUX)
  445.   qsort (data, n_sgl, sizeof (float), (__compar_fn_t) compare);
  446. #else
  447.   qsort (data, n_sgl, sizeof (float), compare);
  448. #endif
  449.  
  450. #ifdef SHOW_SORT
  451.   printf ("\n...sorted data:\n");
  452.   for (i_sgl = 0; i_sgl < n_sgl; i_sgl++)
  453.     printf (" data[%d] = %f\n", i_sgl, *(data + i_sgl));
  454. #endif
  455.  
  456.  
  457.   if (MIN_SET == 0)
  458.     min = *(data + 0);
  459.   if (MAX_SET == 0)
  460.     max = *(data + n_sgl - 1);
  461.  
  462.  
  463.   if (MAKE_HIST == READ_SEGM) {
  464.     min = (float) 1.0;
  465.     max = *(data + n_sgl - 1);
  466.     N_BINS = (int) (max - min) + 1;
  467.   }
  468.  
  469.   if ((hist = (float *) calloc ((size_t) N_BINS, sizeof (float))) == NULL) {
  470.     printf ("\nEH_SGL: mem alloc for hist failed\n");
  471.     exit (1);
  472.   }
  473.  
  474.   bin_width = (max - min) / ((float) (N_BINS - 1));
  475.   construct_hist (n_sgl, data, hist, bin_width, min);
  476.  
  477.   printf ("%s\n", HIST_HEADER);
  478.   printf ("......mean: %lf\n", mean);
  479.   printf ("...std_dev: %lf\n", std_dev);
  480.   printf ("...min: %f, bin_width: %f, max: %f\n", min, bin_width, max);
  481.   for (i = 0; i < N_BINS; i++) {
  482.     printf (" %6.2f", *(hist + i));
  483.     if ((i + 1) % 10 == 0)
  484.       printf ("\n");
  485.   }
  486.   fclose (fpIn);
  487.  
  488. /*
  489.  * ** write output file of type .hdt (see also: .adt, .pdt)
  490.  */
  491.   if (WRITE_FILE == 1) {
  492.     if ((fpOut = fopen (wbuf, "w")) == NULL) {
  493.       printf ("\n...cannot open %s for writing\n",
  494.               wbuf);
  495.       exit (1);
  496.     }
  497.     fprintf (fpOut, "%d\n", N_BINS);
  498.  
  499.     for (i = 0; i < n_parms; i++)
  500.       fprintf (fpOut, "%f\n", foo);
  501.  
  502.     for (i = 0; i < N_BINS; i++)
  503.       fprintf (fpOut, "%f %f\n", (float) i, *(hist + i));
  504.  
  505.     fclose (fpOut);
  506.   }
  507.  
  508.  
  509.   free (hist);
  510.   free (data);
  511. }
  512.